#include "gamepadthread.h"

#include "SDL.h"
#include <QDebug>
#include <QTimer>


GamepadThread *UsergamepadThread;
//定义GamepadState
GamepadState_t GamepadState;

//初始化GamepadState 连接手柄 阻塞的方式进行
GamepadThread::GamepadThread() {

    // while (joystick == NULL) {

    //     msleep(1000);
    // }
    checkForGamepad();
    QTimer *gamepadTimer = new QTimer(this);
    connect(gamepadTimer, SIGNAL(timeout()), this, SLOT(run()));
    gamepadTimer->start(10);
}

//析构函数 断开手柄连接
GamepadThread::~GamepadThread() {
    if (joystick != NULL) {
        SDL_JoystickClose(joystick);
        joystick = NULL;
    }
    SDL_Quit();
}

//GamepadThread的run函数 读取手柄数据并更新GamepadState
//作为槽函数每10ms调用一次
void GamepadThread::run() {
    if (joystick == NULL) {
        return;
    }
    SDL_JoystickUpdate();

    //跟踪手柄按键
    memcpy(&GamepadState.buttons_last, &GamepadState.buttons, sizeof(GamepadState.buttons));


    //读取手柄数据
    // 左右摇杆
    GamepadState.leftAxis.x = (int16_t) (SDL_JoystickGetAxis(joystick, 0)) / 32768.0f; // -1.0f ~ 1.0f
    GamepadState.leftAxis.y = (int16_t) (SDL_JoystickGetAxis(joystick, 1)) / -32768.0f;
    // qDebug()<<"LX:"<<GamepadState.leftAxis.x<<"LY:"<<GamepadState.leftAxis.y;
    GamepadState.rightAxis.x = (int16_t) (SDL_JoystickGetAxis(joystick, 2)) / 32768.0f;
    GamepadState.rightAxis.y = (int16_t) (SDL_JoystickGetAxis(joystick, 3)) / -32768.0f;
    if (GamepadState.leftAxis.y < 0.01 && GamepadState.leftAxis.y > -0.01) {
        GamepadState.leftAxis.y = 0;
    }
    if (GamepadState.rightAxis.y < 0.01 && GamepadState.rightAxis.y > -0.01) {
        GamepadState.rightAxis.y = 0;
    }

    // 左右板机
    GamepadState.leftTrigger = ((int16_t) (SDL_JoystickGetAxis(joystick, 4)) / 65536.0f) + 0.5;
    GamepadState.rightTrigger = ((int16_t) (SDL_JoystickGetAxis(joystick, 5)) / 65536.0f) + 0.5;

    // 按钮
    GamepadState.buttons.A = SDL_JoystickGetButton(joystick, 0);
    GamepadState.buttons.B = SDL_JoystickGetButton(joystick, 1);
    GamepadState.buttons.X = SDL_JoystickGetButton(joystick, 2);
    GamepadState.buttons.Y = SDL_JoystickGetButton(joystick, 3);
    // 手柄按键
    GamepadState.buttons.LeftBumper = SDL_JoystickGetButton(joystick, 4);
    GamepadState.buttons.RightBumper = SDL_JoystickGetButton(joystick, 5);
    GamepadState.buttons.Back = SDL_JoystickGetButton(joystick, 6);
    GamepadState.buttons.Start = SDL_JoystickGetButton(joystick, 7);
    GamepadState.buttons.LeftStick = SDL_JoystickGetButton(joystick, 8);
    GamepadState.buttons.RightStick = SDL_JoystickGetButton(joystick, 9);
    GamepadState.buttons.Home = SDL_JoystickGetButton(joystick, 10);

    // DPad
    int hatState = SDL_JoystickGetHat(joystick, 0);
    GamepadState.buttons.DPadUp = (hatState & SDL_HAT_UP) != 0;
    GamepadState.buttons.DPadDown = (hatState & SDL_HAT_DOWN) != 0;
    GamepadState.buttons.DPadLeft = (hatState & SDL_HAT_LEFT) != 0;
    GamepadState.buttons.DPadRight = (hatState & SDL_HAT_RIGHT) != 0;


    // qDebug() << "LAxisX:" << GamepadState.leftAxis.x << "LAxisY:" << GamepadState.leftAxis.y << "RAxisX:" <<
    //         GamepadState.rightAxis.x << "RAxisY:" << GamepadState.rightAxis.y\
    //         << "LT:" << GamepadState.leftTrigger << "RT:" << GamepadState.rightTrigger\
    //         << "A:" << GamepadState.buttons.A << "B:" << GamepadState.buttons.B << "X:" << GamepadState.buttons.X <<
    //         "Y:" << GamepadState.buttons.Y\
    //         << "LB:" << GamepadState.buttons.LeftBumper << "RB:" << GamepadState.buttons.RightBumper << "Back:" <<
    //         GamepadState.buttons.Back << "Start:" << GamepadState.buttons.Start\
    //         << "Home:" << GamepadState.buttons.Home << "LeftStick:" << GamepadState.buttons.LeftStick << "RightStick:"
    //         << GamepadState.buttons.RightStick\
    //         << "DPadUp:" << GamepadState.buttons.DPadUp << "DPadDown:" << GamepadState.buttons.DPadDown << "DPadLeft:"
    //         << GamepadState.buttons.DPadLeft << "DPadRight:" << GamepadState.buttons.DPadRight;



}

/***
 *@brief 设置手柄震动, 传入参数为左右左右的强度值 与 持续时间
 * @param left 左摇杆的强度值
 * @param right 右摇杆的强度值
 * @param duration 持续时间
 * @return 0 成功 -1 失败
 */
int GamepadThread::setRumble(uint16_t left, uint16_t right, uint32_t duration) {
    if (joystick == NULL) {
        return -1;
    }
    SDL_JoystickRumble(joystick, left, right, duration);
    return 0;
}


//检查手柄函数
void GamepadThread::checkForGamepad() {
    if (joystick != NULL) {
        if (!SDL_JoystickGetAttached(joystick)) {
            SDL_JoystickClose(joystick);
            joystick = NULL;
        }
    } else {
        SDL_Init(SDL_INIT_JOYSTICK);
        int joystickCount = SDL_NumJoysticks();
        if (joystickCount > 0) {
            for (int i = 0; i < joystickCount; i++) {
                joystick = SDL_JoystickOpen(i);
                if (joystick == NULL) {
                    qDebug() << "Gamepad not found! Retrying in 1000ms...";
                }
                else {
                    break;
                }
            }
        }
        else
        {
            qDebug() << "Not game pad dev";
        }
    }
}
